package com.leyou.cart.service;

import com.leyou.auth.pojo.UserInfo;
import com.leyou.cart.interceptor.UserInterceptor;
import com.leyou.cart.pojo.Cart;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String KEY_PREFIX = "cart:uid:";

    public void addCart(Cart cart) {
        // 获取登录用户
        UserInfo user = UserInterceptor.getUserInfo();

        String key = KEY_PREFIX + user.getId();
        String hashKey = String.valueOf(cart.getSkuId());
        Integer num = cart.getNum();

        BoundHashOperations<String, Object, Object> ops = redisTemplate.boundHashOps(key);
        // 判断当前商品是否存在
        if (ops.hasKey(hashKey)) {
            // 存在，修改
            String json = ops.get(hashKey).toString();
            cart = JsonUtils.toBean(json, Cart.class);

            cart.setNum(cart.getNum() + num);
        }

        // 写入 redis
        ops.put(hashKey, JsonUtils.toString(cart));
    }

    public List<Cart> queryCartList() {
        // 获取登录用户
        String key = getKeyByUserInfo();

        // 获取登录用户的购物车信息
        BoundHashOperations<String, Object, Object> ops = redisTemplate.boundHashOps(key);

        List<Cart> cartList = ops.values().stream().map(o -> JsonUtils.toBean(o.toString(), Cart.class))
                .collect(Collectors.toList());

        return cartList;
    }

    public void updateCartNum(Long skuId, Integer num) {

        String key = getKeyByUserInfo();
        String hashKey = skuId.toString();

        // 获取登录用户的购物车信息
        BoundHashOperations<String, Object, Object> ops = redisTemplate.boundHashOps(key);

        if (!ops.hasKey(hashKey)) {
            // 购物车商品不存在，返回 404
            throw new LyException(ExceptionEnum.CART_NOT_FOUND);
        }

        // 查询
        Cart cart = JsonUtils.toBean(ops.get(hashKey).toString(), Cart.class);

        cart.setNum(num);

        // 写入 redis
        ops.put(hashKey, JsonUtils.toString(cart));
    }



    public void deleteCart(Long skuId) {
        // 获取登录用户
        String key = getKeyByUserInfo();
        String hashKey = skuId.toString();
        // 删除购物车商品
        redisTemplate.opsForHash().delete(key, hashKey);
    }

    public void addCarts(List<Cart> cartList) {
        String key = getKeyByUserInfo();

        BoundHashOperations<String, Object, Object> ops = redisTemplate.boundHashOps(key);
        try {
            cartList.forEach(cart -> {
                String hashKey = cart.getSkuId().toString();
                Integer num = cart.getNum();

                // 判断当前商品是否存在
                if (ops.hasKey(hashKey)) {
                    // 存在，修改
                    String json = Objects.requireNonNull(ops.get(hashKey)).toString();
                    cart = JsonUtils.toBean(json, Cart.class);

                    assert cart != null;
                    cart.setNum(cart.getNum() + num);
                }

                // 写入 redis
                ops.put(hashKey, Objects.requireNonNull(JsonUtils.toString(cart)));
            });
        } catch (Exception e) {
            log.error("[购物车服务] 添加购物车异常", e);
            throw new LyException(ExceptionEnum.CART_ADD_ERROR);
        }
    }

    private String getKeyByUserInfo() {
        // 获取登录用户
        UserInfo user = UserInterceptor.getUserInfo();

        // 获取 key
        String key = KEY_PREFIX + user.getId();


        if (!redisTemplate.hasKey(key)) {
            // key 不存在，返回 404
            throw new LyException(ExceptionEnum.CART_NOT_FOUND);
        }
        return key;
    }
}
